home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Utilities Professional 1-1500
/
Utilities Professional 1-1500 (1994)(WPD)[!].iso
/
12511500
/
var1411.dms
/
var1411.adf
/
Source
/
CacheClock1.1.s
< prev
next >
Wrap
Text File
|
1994-02-02
|
39KB
|
2,056 lines
;Comment out next line to make non-detatching program
DETATCH EQU 0
DefaultBuffers EQU 256 number of sectors to remember
WindowSmallX EQU $171 Small window sizes
WindowSmallY EQU $a
WindowBigX EQU $1a8 Big window sizes
WindowBigY EQU $6a
MoreGadget EQU $100 Gadget id numbers
FewerGadget EQU $101
rsreset structure of a remembered sector
NextHash rs.l 1 hash table links
PrevHash rs.l 1
NextInList rs.l 1 links for deallocation of sectors
PrevInList rs.l 1
SectorOffset rs.l 1 disk offset of sector in bytes
WhichDrive rs.w 1 drive number of sector
Sector rs.b $200 sectors data
SectorSize rs.w 0
include "df0:Source/CacheClock.i"
Start movem.l d0/a0,-(sp) save CLI line for later
move.l $4.w,a6 Open dos library
lea DosName(pc),a1
jsr OpenLibrary(a6)
move.l d0,DosBase save base address
beq NoDos
sub.l a1,a1 Standard CLI/workbench startup
move.l $4.w,a6
jsr FindTask(a6)
move.l d0,a2
tst.l pr_CLI(a2)
bne.s CLIcall
lea pr_MsgPort(a2),a0 Started from workbench
move.l $4.w,a6
jsr WaitPort(a6) wait for workbench message
lea pr_MsgPort(a2),a0 get that message
move.l $4.w,a6
jsr GetMsg(a6)
move.l d0,WorkbenchMsg save it for later
movem.l (sp)+,d0/a0 ignore registers
bra.s StartJoin
CLIcall movem.l (sp)+,d0/a3
clr.b -1(a3,d0.l) Null terminate command line
bsr ParseCLI CLI call, so parse command line
beq.s NoDos Bad CLI command ?
StartJoin
IFD DETATCH
;detatch main part of program from CLI
lea Start-4(pc),a0 a0 is ptr to next segment in list
move.l (a0),d3 d3 = BPTR to next hunk
clr.l (a0) unlink second hunk so that it is
; not de-allocated when this terminates
move.l #ProcessName,d1
moveq #0,d2 priority of 0
move.l #4000,d4 4000 byte stack
move.l DosBase,a6
jsr CreateProc(a6) create process
ENDC
IFND DETATCH code for non-detatching program
bsr _main
ENDC
move.l WorkbenchMsg(pc),d0
beq.s NoDos
move.l $4.w,a6 Stop other tasks from interrupting when
jsr Forbid(a6) closing down otherwise workbench crashes
move.l WorkbenchMsg(pc),a1 Workbench open, so signal task ended
jsr ReplyMsg(a6)
NoDos moveq #0,d0
rts
**************** Reads an ascii number from (a3)+ (CLI input)
* GetCLInumber *
**************** returns d0 = number
GetCLInumber
moveq #0,d0 default number = 0
SkipSpaces
moveq #0,d1
move.b (a3),d1 skip spaces after command
cmp.b #" ",d1
beq.s SkipSpc
cmp.b #" ",d1
bne.s StartNumber
SkipSpc addq.w #1,a3
bra.s SkipSpaces
StartNumber
move.b (a3),d1 get next digit
sub.w #"0",d1
bmi.s EndNumber
cmp.w #10,d1
bpl.s EndNumber
add.l d0,d0 multiply d0 by 10 & add d1 quickly
add.l d0,d1
add.l d0,d0
add.l d0,d0
add.l d1,d0
addq.w #1,a3
bra.s StartNumber
EndNumber
rts
************ Execute given CLI commands (a3) = line to parse
* ParseCLI *
************ returns d0=-1, CLI command ok, d0=0, bad CLI command
ParseCLI
lea MyWindow,a0 quick reference for altering structure
GetNextChr
move.b (a3)+,d0 Parse CLI command
beq EndOfCLI
cmp.b #" ",d0 Ignore spaces
beq.s GetNextChr
cmp.b #" ",d0
beq.s GetNextChr
cmp.b #"-",d0 check for switches
beq.s DoSwitches
bra.s BadCLI
DoSwitches
move.b (a3)+,d0 Set switches
beq.s EndOfCLI
cmp.b #" ",d0
beq.s GetNextChr
cmp.b #" ",d0
beq.s GetNextChr
and.w #$5f,d0 conversion from lower to upper case
cmp.w #"B",d0
bne.s NotOptB
bsr GetCLInumber -b(number of blocks)
move.l d0,AddDefaultSectors+2
bra.s DoSwitches
NotOptB cmp.w #"X",d0
bne.s NotOptX
bsr GetCLInumber -x(x position of window)
move.w d0,nw_LeftEdge(a0)
bra.s DoSwitches
NotOptX cmp.w #"Y",d0
bne.s NotOptY
bsr GetCLInumber -y(y position of window)
move.w d0,nw_TopEdge(a0)
bra.s DoSwitches
NotOptY cmp.w #"L",d0
bne.s BadCLI
clr.b GadgetSmall -l (large window)
move.w #WindowBigX,nw_Width(a0) Change window sizes
move.w #WindowBigY,nw_Height(a0)
cmp.w #220,nw_LeftEdge(a0) if window x not changed, then move
bne.s DoSwitches back a bit, so that it will open
move.w #216,nw_LeftEdge(a0)
bra.s DoSwitches
EndOfCLI
moveq #-1,d0 exit - CLI command OK
rts
BadCLI move.l $4.w,a6
move.l DosBase,a6 Get CLI output file handle
jsr Output(a6)
move.l d0,d1
move.l #BadCLIMsg,d2 write message to CLI window
move.l #BadEndMsg-BadCLIMsg,d3
jsr Write(a6)
move.l a6,a1 close dos.library
move.l $4.w,a6
jsr CloseLibrary(a6)
moveq #0,d0 exit - error
rts
WorkbenchMsg dc.l 0 Workbench calling message
BadCLIMsg
dc.b "CacheClock [-options]",10
dc.b " -b number Default number of blocks",10
dc.b " -l Large window",10
dc.b " -x number Default X co-ordinate",10
dc.b " -y number Default Y co-ordinate",10,10
dc.b "E.g. CacheClock -b500 -lx200 -y10",10,10,0
BadEndMsg
DosName dc.b "dos.library",0
even word aling program counter
IFD DETATCH
;for detatching version, want main part in a separate hunk
SECTION Program,CODE
ENDC
_main move.l a7,StartSP Save start SP
lea IntName(pc),a1
move.l $4.w,a6
jsr OpenLibrary(a6)
move.l d0,IntBase
beq NoInt
lea GfxName(pc),a1
jsr OpenLibrary(a6)
move.l d0,GfxBase
beq NoGfx
bsr GetTrackdiskBase Get trackdisk library
tst.l d0
beq.s Exit
bsr OpenProgramPort check to see if already active
bne Exit
bsr OpenMyWindow Open window, & draw it if needed
beq.s ExitPort
jsr OpenMyTimer
beq.s ExitTimer
bsr AddDefaultSectors Get 256 blocks
move.b GadgetSmall(pc),d0
bne.s NoBigWind
bsr DrawBigWindow
NoBigWind
bsr RefreshStats redraw window stats if big window
bsr PatchTrackdisk Install trackdisk patch
CheckGadgetsLoop
bsr CheckGadgets
tst.l d0 Close window pressed ?
bne.s FreeAllSectors
lea TimerPort(pc),a0 Check for timer interrupt
move.l $4.w,a6
jsr GetMsg(a6)
tst.l d0
beq.s NotTimerInt
bsr SetTimer reset timer for one second
NotTimerInt
bsr RefreshStats
move.l Signals(pc),d0
move.l $4.w,a6
jsr Wait(a6)
bra.s CheckGadgetsLoop
FreeAllSectors
bsr FreeSector Free memory used by program
tst.l d0
bne.s FreeAllSectors
bsr CloseMyTimer
ExitTimer
bsr CloseMyWindow
ExitPort
bsr CloseProgramPort
bsr RestoreTrackdisk
Exit move.l GfxBase(pc),a1 Close used libraries
move.l $4.w,a6
jsr CloseLibrary(a6)
NoGfx move.l IntBase(pc),a1
move.l $4.w,a6
jsr CloseLibrary(a6)
NoInt move.l StartSP(pc),a7
;for detatching version, free memory used by second part of program, and
;then do a rts. This can be done easily by Jumping to a UnloadSeg call
;We cannot JSR to UnLoadSeg, then rts, since this code area will not be
;allocated, and a crash may occur.
IFD DETATCH
move.l #_main-4,d1 make BPTR to first section
lsr.l #2,d1
move.l DosBase(pc),a6
jmp UnLoadSeg(a6) free memory used by detached process
ENDC
;for non-detaching version, just do a rts
IFND DETATCH
rts
ENDC
******************* Opens program port, & checks to see if program
* OpenProgramPort * is already active (quits if so)
******************* returns d0=0 port opened ok
OpenProgramPort
move.l $4.w,a6
jsr Forbid(a6)
lea PortName(pc),a1
jsr FindPort(a6)
move.l d0,d4
bne.s AlreadyActive
lea ProgramPort(pc),a2
bsr InitPort
tst.l d0
beq.s AlreadyActive
move.l #PortName,LN_NAME(a2)
move.l a2,a1
move.l $4.w,a6
jsr AddPort(a6)
moveq #0,d4
AlreadyActive
jsr Permit(a6)
move.l d4,d0
rts
******************** Closes the main programs port & frees it's signal
* CloseProgramPort *
********************
CloseProgramPort
move.l $4.w,a6
jsr Forbid(a6)
lea ProgramPort(pc),a1 Remove port
jsr RemPort(a6)
moveq #0,d0 free signal bit used by port
move.b MP_SIGBIT(a1),d0
lea ProgramPort(pc),a1
jsr FreeSignal(a6)
jmp Permit(a6)
ProcessName dc.b "CacheClock",0
ScreenName dc.b "CacheClock Disk accelerator and Clock",0
TitleName dc.b "CacheClock V1.1 © 1993 Justin Leck",0
GfxName dc.b "graphics.library",0
IntName dc.b "intuition.library",0
FontName dc.b "topaz.font",0
PortName dc.b "CacheClock.port",0
TimerName dc.b "timer.device",0
TrackName dc.b "trackdisk.device",0
even
**************** Open the programs window & font
* OpenMyWindow *
**************** returns d0=0, window open bad
OpenMyWindow
lea MyWindow(pc),a0
move.l IntBase(pc),a6
jsr OpenWindow(a6)
move.l d0,Window
beq.s BadOpen
move.l Window(pc),a0
move.l wd_RPort(a0),RastPort Get windows rastport
move.l wd_UserPort(a0),a0
moveq #0,d0
move.b $f(a0),d0
moveq #1,d1
asl.l d0,d1
move.l d1,Signals Get windows signal
lea FontAttr(pc),a0 Open Topaz 8 font
move.l GfxBase(pc),a6
jsr OpenFont(a6)
move.l d0,TopazFont
beq.s NoFont
move.l d0,a0
move.l RastPort(pc),a1 use that font
move.l GfxBase(pc),a6
jsr SetFont(a6)
NoFont
move.l a2,-(a7)
move.l Window(pc),a0
lea TitleName(pc),a1
lea ScreenName(pc),a2
move.l IntBase(pc),a6
jsr SetWindowTitles(a6)
move.l (a7)+,a2
BadOpen move.l Window(pc),d0
rts
***************** Shut my window & font
* CloseMyWindow *
*****************
CloseMyWindow
move.l Window(pc),d0
beq.s NoWind
move.l $4.w,a6
DelNMsg move.l Window(pc),a0 Reply to all unanswered messages
move.l wd_UserPort(a0),a0
jsr GetMsg(a6)
tst.l d0
beq.s LastMsg
move.l d0,a1
jsr ReplyMsg(a6)
bra.s DelNMsg
LastMsg
move.l Window(pc),a0
move.l IntBase(pc),a6
jsr CloseWindow(a6)
NoWind move.l TopazFont(pc),d0
beq.s NoFnt
move.l d0,a1
move.l GfxBase(pc),a6
jsr CloseFont(a6)
NoFnt rts
************ Start timer running & request signal in 1 second
* SetTimer *
************
SetTimer
lea TimerIOreq(pc),a1
move.w #TR_ADDREQUEST,IO_COMMAND(a1)
move.l #1,IOTV_TIME+TV_SECS(a1)
clr.l IOTV_TIME+TV_MICRO(a1)
move.l $4.w,a6
jmp SendIO(a6)
*************** Opens timer B, and sets it to interrupt every 2 seconds
* OpenMyTimer *
*************** returns d0=0, open timer failed
OpenMyTimer
lea TimerPort(pc),a2 Set up port for IO request
bsr InitPort
tst.l d0
beq.s NoTimePort
lea TimerIOreq(pc),a1
move.b #NT_MESSAGE,LN_TYPE(a1) set up IO request structure
move.l a2,MN_REPLYPORT(a1)
move.w #IOSTD_SIZE,MN_LENGTH(a1)
lea TimerName(pc),a0 Open timer.device
moveq #1,d0
moveq #0,d1
move.l $4.w,a6
jsr OpenDevice(a6)
tst.l d0
bne.s NoTimerDevice
lea TimerPort(pc),a0 Get Timers signal
moveq #0,d0
move.b $f(a0),d0
moveq #1,d1
asl.l d0,d1
or.l d1,Signals
bsr SetTimer Set timer to interrupt in 2 secs
moveq #1,d0
NoTimePort
rts
NoTimerDevice
lea TimerPort(pc),a0
moveq #0,d0 free signal bit used by port
move.b MP_SIGBIT(a2),d0
move.l $4.w,a6
jmp FreeSignal(a6)
**************** Shuts down the use of timer.device
* CloseMyTimer *
****************
CloseMyTimer
lea TimerIOreq(pc),a1 Timer still doing IO
move.l $4.w,a6
jsr CheckIO(a6)
tst.l d0
bne.s FreeTimerMsg
lea TimerIOreq(pc),a1 yes, so abort it
move.l $4.w,a6
jsr AbortIO(a6)
FreeTimerMsg
lea TimerPort(pc),a0 Free messages used by port
jsr GetMsg(a6)
tst.l d0
bne.s FreeTimerMsg
lea TimerIOreq(pc),a1 close timer.device
move.l $4.w,a6
jsr CloseDevice(a6)
lea TimerPort(pc),a0
moveq #0,d0 free signal bit used by port
move.b MP_SIGBIT(a2),d0
jmp FreeSignal(a6)
************ Sets up port a2 and grabs a signal for it
* InitPort *
************
InitPort
clr.l LN_NAME(a2)
clr.b LN_PRI(a2)
move.b #NT_MSGPORT,LN_TYPE
clr.b MP_FLAGS(a2)
moveq #-1,d0
move.l $4.w,a6
jsr AllocSignal(a6)
cmp.l #$ffffffff,d0
beq.s NoSignals
move.b d0,MP_SIGBIT(a2)
sub.l a1,a1
move.l $4.w,a6
jsr FindTask(a6)
move.l d0,MP_SIGTASK(a2)
lea MP_MSGLIST(a2),a0
move.l a0,(a0)
addq.l #4,(a0)
clr.l LH_TAIL(a0)
move.l a0,LH_TAILPRED(a0)
move.l a2,d0
rts
NoSignals
moveq #0,d0
rts
******************** Gets library base for trackdisk.device
* GetTrackdiskBase *
********************
GetTrackdiskBase
move.l a2,-(sp)
lea TrackdiskPort(pc),a2 Set up port for IO request
bsr InitPort
tst.l d0
beq.s BadTrackPort
lea TrackdiskIOreq(pc),a1
move.b #NT_MESSAGE,LN_TYPE(a1) set up IO request structure
move.l a2,MN_REPLYPORT(a1)
move.w #IOSTD_SIZE,MN_LENGTH(a1)
lea TrackName(pc),a0 open trackdisk.device
moveq #0,d0
moveq #0,d1
move.l $4.w,a6
jsr OpenDevice(a6)
tst.l d0
bne.s BadTrackdisk
lea TrackdiskIOreq(pc),a0 Get trackdisk library offsets
move.l IO_DEVICE(a0),TrackBase
lea TrackdiskIOreq(pc),a1 close trackdisk.device
move.l $4.w,a6
jsr CloseDevice(a6)
BadTrackdisk
moveq #0,d0 free signal bit used by port
move.b MP_SIGBIT(a2),d0
jsr FreeSignal(a6)
move.l TrackBase(pc),d0
BadTrackPort
move.l (sp)+,a2
rts
******************
* PatchTrackdisk *
******************
PatchTrackdisk
move.l $4.w,a6 Disable system
jsr Forbid(a6)
jsr Disable(a6)
move.l TrackBase(pc),a1 Install trackdisk patch
lea -$1e.w,a0
move.l #NewTrackDisk,d0
jsr SetFunction(a6)
move.l d0,OldTrackDisk+2
jsr Enable(a6) Enable system
jmp Permit(a6)
********************
* RestoreTrackdisk *
********************
RestoreTrackdisk
move.l $4.w,a6 Disable system
jsr Forbid(a6)
jsr Disable(a6)
move.l TrackBase(pc),a1 restore trackdisk
lea -$1e.w,a0
move.l OldTrackDisk+2(pc),d0
jsr SetFunction(a6)
jsr Enable(a6) Enable system
jmp Permit(a6)
DrawSmall rts
***************** Draws the outline for the big window
* DrawBigWindow *
*****************
DrawBigWindow
move.b GadgetSmall(pc),d0
bne.s DrawSmall
bsr SetColour0 Clear big window
move.l Window(pc),a0
moveq #4,d0
moveq #$c,d1
move.w wd_Width(a0),d2
subq.w #8,d2
move.w wd_Height(a0),d3
subq.w #3,d3
move.l RastPort(pc),a1
move.l GfxBase,a6
jsr RectFill(a6)
moveq #$6,d0 Draw infotext panel
moveq #$c,d1
moveq #$5a,d2
moveq #$46,d3
bsr DrawPanel
moveq #$a,d0 Draw infotext underline
moveq #$1b,d1
move.l #$52,d2
moveq #1,d3
bsr DrawWb2Box
moveq #$64,d0 Draw drive stats panel
moveq #$c,d1
move.l #$f0,d2
moveq #$46,d3
bsr DrawPanel
moveq #$68,d0 draw drive stats underline
moveq #$1b,d1
move.l #$e8,d2
moveq #1,d3
bsr DrawWb2Box
move.l #$158,d0 Draw panel for totals
moveq #$c,d1
moveq #$4a,d2
moveq #$46,d3
bsr DrawPanel
lea InfoTx(pc),a2 Draw all text onto window
bsr DrawTexts
move.l #$15c,d0
moveq #$1b,d1
moveq #$42,d2
moveq #$1,d3
bsr DrawWb2Box
moveq #$a,d0 Fewer box
moveq #$57,d1
moveq #$54,d2
moveq #$c,d3
bsr DrawWb2Box
move.l #$15b,d0 More box
moveq #$57,d1
moveq #$42,d2
moveq #$c,d3
bsr DrawWb2Box
moveq #$64,d0 Time & memory box
moveq #$56,d1
move.l #$f0,d2
moveq #$e,d3
bra DrawPanel
**************** Check for gadget presses, and timer interrupts
* CheckGagdets *
**************** returns d0 = 0, close window pressed
CheckGadgets
movem.l d4/a2/a3,-(a7)
NextWindowMsg
move.l Window(pc),a0
move.l wd_UserPort(a0),a0
move.l $4.w,a6
jsr GetMsg(a6)
tst.l d0
beq CheckMoreFew
move.l d0,a2
move.l d0,a1
move.l im_Class(a1),d4
move.l im_IAddress(a1),a3
jsr ReplyMsg(a6)
cmp.l #GADGETDOWN,d4 Check for fewer/more pressed
bne.s NotGadDown
cmp.w #MoreGadget,gg_GadgetID(a3)
bne.s NoMoreP
st MorePressed
NoMoreP cmp.w #FewerGadget,gg_GadgetID(a3)
bne.s NotGadDown
st FewerPressed
NotGadDown
cmp.l #GADGETUP,d4 Check for fewer/more released
bne.s NotGadgetUp
cmp.w #MoreGadget,gg_GadgetID(a3)
bne.s NoMoreR
clr.b MorePressed
NoMoreR cmp.w #FewerGadget,gg_GadgetID(a3)
bne.s NotGadgetUp
clr.b FewerPressed
NotGadgetUp
cmp.l #MENUPICK,d4
bne.s NotMenuPick
move.b GadgetSmall(pc),d0
beq.s ToSmall
bsr ExpandWindow go big window
bra.s NotMenuPick
ToSmall bsr ShrinkWindow go small window
NotMenuPick
cmp.l #CLOSEWINDOW,d4 Check for Close window
beq.s CloseWind
CheckMoreFew
move.b MorePressed(pc),d0 Check for more pressed / released
beq.s NoChkMore
btst #7,MoreGadgFlags+1
bne.s MoreHit
clr.b MorePressed more released
bra.s NoChkFew
MoreHit bsr AddSector more still pressed
Refresh bsr RefreshStats
moveq #1,d1
move.l DosBase(pc),a6
jsr Delay(a6)
bra NextWindowMsg
FewerHit
bsr FreeSector fewer still pressed
bra.s Refresh
NoChkMore
move.b FewerPressed(pc),d0 Check for fewer pressed / released
beq.s NoChkFew
btst #7,FewerGadgFlags+1
bne.s FewerHit
clr.b FewerPressed fewer released
NoChkFew
moveq #0,d0
bra.s EndMsgs
CloseWind
moveq #1,d0
EndMsgs movem.l (a7)+,d4/a2/a3
rts
************* Draws a panel at (d0,d1), width (d2,d3) & clears the insides
* DrawPanel *
*************
DrawPanel
movem.l d0/d1/d2/d3,-(sp)
bsr DrawWb2Box
movem.l (sp),d0/d1/d2/d3
addq.w #1,d0
addq.w #1,d1
subq.w #2,d2
subq.w #2,d3
bsr DrawWb2Box
bsr SetColour0 Clear box just drawn
movem.l (sp)+,d0/d1/d2/d3
add.w d0,d2
add.w d1,d3
addq.w #3,d0
addq.w #2,d1
subq.w #3,d2
subq.w #2,d3
move.l RastPort(pc),a1
move.l GfxBase,a6
jmp RectFill(a6)
************* Displays onscreen a number of texts, from (a2)+
* DrawTexts *
*************
DrawTexts
bsr SetColour1
DrawNextText
moveq #0,d0
move.w (a2)+,d0
cmp.w #-1,d0
beq.s EndDrawTexts
moveq #0,d1
move.w (a2)+,d1
move.l RastPort(pc),a1
move.l GfxBase(pc),a6
jsr Move(a6) move to start of text
move.l a2,a0
ToEndSt tst.b (a2)+
bne.s ToEndSt
move.l a2,d0
sub.l a0,d0
move.w d0,d1 word align a0 to next text to draw
and.w #1,d1
add.w d1,a2
subq.w #1,d0
move.l RastPort(pc),a1
move.l GfxBase(pc),a6
jsr Text(a6)
bra.s DrawNextText
EndDrawTexts
rts
InfoTx dc.w $1f,$18
dc.b "Drive",0
dc.w $1f,$26
dc.b "Reads",0
dc.w $1b,$30
dc.b "Writes",0
dc.w $17,$3a
dc.b "ReadHits",0
dc.w $b,$44
dc.b "Percentage",0
dc.w $15,$4e
dc.b "Buffers",0
dc.w $80,$18
dc.b "A",0
dc.w $ba,$18
dc.b "B",0
dc.w $f4,$18
dc.b "C",0
dc.w $12e,$18
dc.b "D",0
dc.w $21,$60
dc.b "Fewer",0
dc.w $16d,$60
dc.b "More",0
dc.w $169,$19
dc.b "Total",0
dc.w -1
SpacesTx dc.b " ",0
TimeMemoryTx dc.b "Free:"
MemoryStore dc.b "???????? Time:"
TimeStore dc.b "??:??:??"
SmallMenu dc.b " Chip:"
ChipAmount dc.b "???? Fast:"
FastAmount dc.b "????? Time:"
SmallTime dc.b "??:??:?? "
nums dc.l 100000000,10000000,1000000,100000,10000,1000,100,10,1,-1
************** writes number d0 into buffer (a1)
* TextNumber * leading zeros are omitted
************** returns d0 = length of string
TextNumber
movem.l d6/d7,-(sp)
move.l a1,-(sp)
moveq #0,d7 d7 = 1, include zeros
lea nums(pc),a0
NextDivisor
move.l (a0)+,d1
bmi.s NumberDone
moveq #"0",d6
CompareAgain
cmp.l d1,d0
blt.s NoSubtract
addq.w #1,d6
sub.l d1,d0
moveq #1,d7
bra.s CompareAgain
NoSubtract
tst.w d7
beq.s NextDivisor
move.b d6,(a1)+ Add digit to display buffer
bra.s NextDivisor
NumberDone
tst.w d7
bne.s NumberNot0
move.b #"0",(a1)+
NumberNot0
clr.b (a1)
sub.l (sp)+,a1
move.l a1,d0
movem.l (sp)+,d6/d7
rts
NumberBuffer ds.b 10
********************** Displays number (d2) at (d0,d1)
* PrintCentralNumber *
**********************
PrintCentralNumber
movem.l d0/d1/d2/d3,-(sp)
move.l RastPort(pc),a1 Clear space for number to go in
move.l GfxBase,a6
jsr Move(a6)
lea SpacesTx(pc),a0
moveq #7,d0
move.l RastPort(pc),a1
move.l GfxBase(pc),a6
jsr Text(a6)
move.l $8(sp),d0 Convert number to ascii
lea NumberBuffer(pc),a1
bsr TextNumber
move.l d0,d3
lea NumberBuffer(pc),a0 Get length of string in pixels
move.l RastPort(pc),a1
move.l GfxBase(pc),a6
jsr TextLength(a6)
lsr.l #1,d0
moveq #$3a,d1
sub.l d0,d1
move.l d1,d0
add.l (sp),d0
sub.l #$1e,d0
move.l 4(sp),d1
move.l RastPort(pc),a1
move.l GfxBase,a6
jsr Move(a6)
lea NumberBuffer(pc),a0
move.l d3,d0
move.l RastPort(pc),a1
move.l GfxBase(pc),a6
jsr Text(a6)
movem.l (sp)+,d0/d1/d2/d3
rts
************** converts system date into ascii values from (a0)+
* GetSysTime *
**************
GetSysTime
move.l a0,-(sp)
move.l #Date,d1
move.l DosBase(pc),a6
jsr DateStamp(a6)
lea Date(pc),a0
move.l (sp)+,a1
move.l ds_Minute(a0),d0
moveq #"0",d1 Work out tens of hours
CalcHT cmp.l #600,d0
blt.s EndHrT
addq.w #1,d1
sub.l #600,d0
bra.s CalcHT
EndHrT move.b d1,(a1)
moveq #"0",d1
CalcHrs cmp.l #60,d0 work out hours
blt.s EndHrs
addq.w #1,d1
sub.l #60,d0
bra.s CalcHrs
EndHrs move.b d1,1(a1)
moveq #"0",d1
CalcMT cmp.l #10,d0 work out tens of minutes
blt.s EndMinT
addq.w #1,d1
sub.l #10,d0
bra.s CalcMT
EndMinT move.b d1,3(a1)
add.w #$30,d0 get minutes
move.b d0,4(a1)
move.l ds_Tick(a0),d0
moveq #"0",d1
CalcST cmp.l #500,d0 work out tens of seconds
blt.s EndSecT
addq.w #1,d1
sub.l #500,d0
bra.s CalcST
EndSecT move.b d1,6(a1)
moveq #"0",d1
CalcSec cmp.l #50,d0 work out seconds
blt.s EndSecs
addq.w #1,d1
sub.l #50,d0
bra.s CalcSec
EndSecs move.b d1,7(a1)
rts
**************** Redraws numbers on screen if needed
* RefreshStats *
****************
RefreshStats
bsr SetColour1
move.b GadgetSmall(pc),d0
bne.s SmallRefresh
bsr DisplayMemoryTime
bsr DisplayReads
bsr DisplayWrites
bsr DisplayReadHits
bsr DisplayBuffers
rts
SmallRefresh
lea ChipAmount(pc),a0
moveq #4,d0
ClrMems move.b #" ",0(a0,d0.w)
move.b #" ",FastAmount-ChipAmount+1(a0,d0.w)
dbra d0,ClrMems
move.b #" ",FastAmount-ChipAmount(a0)
moveq #2,d1 Get amount of chip ram
move.l $4.w,a6
jsr AvailMem(a6)
moveq #10,d1
lsr.l d1,d0
lea ChipAmount(pc),a1 Copy Chip amount
bsr TextNumber
lea ChipAmount(pc),a1 change \0 to a space
move.b #" ",0(a1,d0.w)
moveq #4,d1 Get amount of fast ram
move.l $4.w,a6
jsr AvailMem(a6)
moveq #10,d1
lsr.l d1,d0
lea FastAmount(pc),a1 Copy fast amount
bsr TextNumber
lea FastAmount(pc),a1
move.b #" ",0(a1,d0.w) change \0 to a space
lea SmallTime(pc),a0
bsr GetSysTime
moveq #$1d,d0
moveq #$7,d1
move.l RastPort(pc),a1
move.l GfxBase,a6
jsr Move(a6)
lea SmallMenu(pc),a0 Display time & memory left
moveq #36,d0
move.l RastPort(pc),a1
move.l GfxBase(pc),a6
jmp Text(a6)
********************* Displays memory, time and totals
* DisplayMemoryTime *
*********************
DisplayMemoryTime
movem.l d2/d4,-(sp)
lea MemoryStore(pc),a0 Clear last memory count
moveq #8,d0
ClrMemSt
move.b #" ",0(a0,d0.w)
dbra d0,ClrMemSt
moveq #2,d1 Get amount of chip ram
move.l $4.w,a6
jsr AvailMem(a6)
move.l d0,d4
moveq #4,d1 Add to the amount of fast ram
jsr AvailMem(a6)
add.l d4,d0
lea MemoryStore(pc),a1 Copy memory number
bsr TextNumber
lea MemoryStore(pc),a1 Copy memory number
move.b #" ",0(a1,d0.w)
lea TimeStore(pc),a0
bsr GetSysTime
moveq #$6c,d0
moveq #$60,d1
move.l RastPort(pc),a1
move.l GfxBase,a6
jsr Move(a6)
lea TimeMemoryTx(pc),a0 Display time & memory left
moveq #28,d0
move.l RastPort(pc),a1
move.l GfxBase(pc),a6
jsr Text(a6)
move.l TotalReads(pc),d2 Display number of reads if changed
move.b ForcePrint(pc),d0 Must print ?
bne.s FrceRds
cmp.l LastTotalReads(pc),d2
beq.s ReadsSame
FrceRds move.l d2,LastTotalReads
move.l #$161,d0
moveq #$26,d1
bsr PrintCentralNumber
ReadsSame
move.l TotalWrites(pc),d2 Display number of writes if changed
move.b ForcePrint(pc),d0 Must print ?
bne.s FrceWts
cmp.l LastTotalWrites(pc),d2
beq.s WritesSame
FrceWts move.l d2,LastTotalWrites
move.l #$161,d0
moveq #$30,d1
bsr PrintCentralNumber
WritesSame
move.l TotalRHits(pc),d2 Display number of readhits if changed
move.b ForcePrint(pc),d0 Must print ?
bne.s FrceRHt
cmp.l LastTotalRHits(pc),d2
beq.s RHitsSame
FrceRHt move.l d2,LastTotalRHits
move.l #$161,d0
moveq #$3a,d1
bsr PrintCentralNumber
RHitsSame
move.l NumBlocks(pc),d2 Display number of blocks if changed
move.b ForcePrint(pc),d0 Must print ?
bne.s FrceBlk
cmp.l LastNumBlocks(pc),d2
beq.s BlocksSame
FrceBlk move.l d2,LastNumBlocks
move.l #$161,d0
moveq #$4e,d1
bsr PrintCentralNumber
BlocksSame
movem.l (sp)+,d2/d4
rts
**************** Displays the number of Reads
* DisplayReads *
****************
DisplayReads
movem.l d2/d4,-(a7)
moveq #0,d4
DispNxtRead
move.l d4,d0
add.l d0,d0
add.l d0,d0
lea NumReads(pc),a0
move.l 0(a0,d0.w),d2
move.b ForcePrint(pc),d1 Must print ?
bne.s FrceRd
cmp.l $10(a0,d0.w),d2
beq.s NoReadChange
FrceRd move.l d2,$10(a0,d0.w)
move.l d4,d0 Work out X position
mulu #$3a,d0
add.l #$68,d0
move.l d0,-(sp) Save X pos for printing percentage
moveq #$26,d1
bsr PrintCentralNumber
move.l d4,d0 Work out percentage
add.l d0,d0 = ReadHits*100/Reads
add.l d0,d0
lea NumReads(pc),a0
move.l 0(a0,d0.l),d1 Trap for division by 0
beq.s Reads0
move.l d1,-(sp)
lea NumReadHits(pc),a0
move.l 0(a0,d0.l),d0
moveq #100,d1
jsr LongMult
move.l d0,d1
move.l (sp)+,d0
jsr LongDivide
move.l d0,d2
bra.s ReadsN
Reads0 moveq #0,d2
ReadsN move.l (sp)+,d0 Display percentage
moveq #$44,d1
bsr PrintCentralNumber
NoReadChange
addq.l #1,d4
cmp.l #4,d4
bne.s DispNxtRead
movem.l (a7)+,d2/d4
rts
***************** Displays the number of Writes
* DisplayWrites *
*****************
DisplayWrites
movem.l d2/d4,-(a7)
moveq #0,d4
DispNxtWrite
move.l d4,d0
asl.l #2,d0
lea NumWrites(pc),a0
move.l 0(a0,d0.w),d2
move.b ForcePrint(pc),d1 Must print ?
bne.s FrceWte
cmp.l $10(a0,d0.w),d2
beq.s NoWriteChange
FrceWte move.l d2,$10(a0,d0.w)
move.l d4,d0
mulu #$3a,d0
add.l #$68,d0
moveq #$30,d1
bsr PrintCentralNumber
NoWriteChange
addq.l #1,d4
cmp.l #4,d4
bne.s DispNxtWrite
movem.l (a7)+,d2/d4
rts
******************* Displays the number of Read hits
* DisplayReadHits *
*******************
DisplayReadHits
movem.l d2/d4,-(a7)
moveq #0,d4
DispNxtReadHit
move.l d4,d0
asl.l #2,d0
lea NumReadHits(pc),a0
move.l 0(a0,d0.w),d2
move.b ForcePrint(pc),d1 Must print ?
bne.s FrceRdH
cmp.l $10(a0,d0.w),d2
beq.s NoReadHitChange
FrceRdH move.l d2,$10(a0,d0.w)
move.l d4,d0
mulu #$3a,d0
add.l #$68,d0
moveq #$3a,d1
bsr PrintCentralNumber
NoReadHitChange
addq.l #1,d4
cmp.l #4,d4
bne.s DispNxtReadHit
movem.l (a7)+,d2/d4
rts
****************** Displays the number of buffers
* DisplayBuffers *
******************
DisplayBuffers
movem.l d2/d4,-(a7)
moveq #0,d4
DispNxtBuf
move.l d4,d0
asl.l #2,d0
lea NumBuffers(pc),a0
move.l 0(a0,d0.w),d2
move.b ForcePrint(pc),d1 Must print ?
bne.s FrceBuf
cmp.l $10(a0,d0.w),d2
beq.s NoBufChange
FrceBuf move.l d2,$10(a0,d0.w)
move.l d4,d0
mulu #$3a,d0
add.l #$68,d0
moveq #$4e,d1
bsr PrintCentralNumber
NoBufChange
addq.l #1,d4
cmp.l #4,d4
bne.s DispNxtBuf
movem.l (a7)+,d2/d4
rts
************** Draws a workbench 2 style box at (d0,d1) width (d2,d3)
* DrawWb2Box *
**************
DrawWb2Box
add.l d0,d2
add.l d1,d3
movem.l d0/d1/d2/d3,-(sp)
move.l d3,d1
move.l RastPort(pc),a1
move.l GfxBase(pc),a6
jsr Move(a6)
bsr SetColour2
movem.l (sp),d0/d1
move.l RastPort(pc),a1
jsr Draw(a6)
move.l 8(sp),d0
move.l 4(sp),d1
move.l RastPort(pc),a1
jsr Draw(a6)
bsr SetColour1
move.l RastPort(pc),a1
movem.l 8(sp),d0/d1
move.l RastPort(pc),a1
jsr Draw(a6)
move.l (sp),d0
move.l 12(sp),d1
move.l RastPort(pc),a1
jsr Draw(a6)
lea $10(sp),sp
rts
**************** Changes window to the large one with stats
* ExpandWindow *
****************
ExpandWindow
move.b GadgetSmall(pc),d0
beq WindowAlreadyBig
clr.b GadgetSmall
move.l Window(pc),a0
move.l wd_WScreen(a0),a1
move.w $c(a1),d0 Check for enough room in X direction
sub.w wd_LeftEdge(a0),d0
sub.w #$1aa,d0
ext.l d0
bmi.s XposBAD
moveq #0,d0
XposBAD
move.w $e(a1),d1 Check for enough room in Y direction
sub.w wd_TopEdge(a0),d1
sub.w #$70,d1
ext.l d1
bmi.s YposBAD
moveq #0,d1
YposBAD
tst.l d0
bne.s MvWindo
tst.l d1
beq.s NoMoveWindow
MvWindo move.l wd_LeftEdge(a0),-(sp) Not enough room, so move window
move.l IntBase(pc),a6
jsr MoveWindow(a6)
CheckWindowMoved
move.l Window(pc),a0 Window been moved yet
move.l wd_LeftEdge(a0),d0
cmp.l (sp),d0
bne.s MvdWind
moveq #1,d1 no, so wait a tick
move.l DosBase(pc),a6
jsr Delay(a6)
bra.s CheckWindowMoved
MvdWind addq.w #4,sp
NoMoveWindow
moveq #WindowBigX-WindowSmallX,d0
moveq #WindowBigY-WindowSmallY,d1
move.l Window(pc),a0
move.l IntBase(pc),a6
jsr SizeWindow(a6)
WaitExpandWind
move.l Window(pc),a0 Wait for window to expand
cmp.w #WindowBigX,wd_Width(a0)
beq.s WindowExpanded
moveq #1,d1
move.l DosBase(pc),a6
jsr Delay(a6)
bra.s WaitExpandWind
WindowExpanded
bsr DrawBigWindow
st ForcePrint
bsr RefreshStats
clr ForcePrint
WindowAlreadyBig
rts
**************** shrinks the window to the small sized one
* ShrinkWindow *
****************
ShrinkWindow
move.b GadgetSmall(pc),d0 Is window already small ?
bne WindowAlreadySmall
st GadgetSmall
moveq #WindowSmallX-WindowBigX,d0 No, so shrink it
moveq #WindowSmallY-WindowBigY,d1
move.l Window(pc),a0
move.l IntBase(pc),a6
jsr SizeWindow(a6)
WindowAlreadySmall
rts
************** Searchs hash list for sector IO_OFFSET(a1), drive d2
* FindSector * d0 = 0, search failed. d0=1, a0=Sector
**************
FindSector
move.l IO_OFFSET(a1),d0
lsr.l #7,d0
and.l #$1fc,d0
lea SectorHeaders(pc),a2
add.w d0,a2
move.l (a2),d0
SearchHash
beq.s NoSector
move.l d0,a0
cmp.w WhichDrive(a0),d2
bne.s WrongSector
move.l SectorOffset(a0),d0
cmp.l IO_OFFSET(a1),d0
beq.s RightSector
WrongSector
move.l NextHash(a0),d0
bra.s SearchHash
RightSector
moveq #1,d0
rts
NoSector
rts
**************** Trackdisk patch, so that all read / writes are logged
* NewTrackDisk * and cached if possible
****************
NewTrackDisk
movem.l d2/a2,-(a7)
move.l IO_UNIT(a1),d1 Add current unit to list of drives
lea DevUnits(pc),a0
moveq #0,d2 d2 = current drive number * 4
TryNdev tst.l (a0)
bne.s IsDvice
move.l d1,(a0)
bra.s FoundDevice
IsDvice cmp.l (a0)+,d1
beq.s FoundDevice
addq.w #4,d2
cmp.w #$10,d2
bne.s TryNdev
FoundDevice
cmp.w #CMD_READ,IO_COMMAND(a1)
bne.s NotCMD_READ
addq.l #1,TotalReads reading sector
lea NumReads(pc),a0
addq.l #1,0(a0,d2.w)
bsr.s FindSector sector in cache ?
beq.s IgnoreCMD
bsr ReadFromCache yes, so copy it
bra DoneIO
NotCMD_READ
cmp.w #CMD_WRITE,IO_COMMAND(a1)
bne.s NotCMD_WRITE
addq.l #1,TotalWrites writing sector
lea NumWrites(pc),a0
addq.l #1,0(a0,d2.w)
bsr WriteToCache
bra.s IgnoreCMD
NotCMD_WRITE
cmp.w #CMD_CLEAR,IO_COMMAND(a1)
bne.s IgnoreCMD
bsr DiskChange disk change
IgnoreCMD
move.l a1,-(a7)
OldTrackDisk
jsr $0
move.l (a7)+,a1
cmp.w #CMD_READ,IO_COMMAND(a1)
bne.s DoneIO
bsr SaveReadSector
DoneIO movem.l (a7)+,d2/a2
rts
************* Adds a sector to the list of sectors
* AddSector *
************* returns d0=0, ran out of memory
AddSector
move.l a2,-(a7)
move.l #$10001,d1
move.l #SectorSize,d0
move.l $4.w,a6
jsr AllocMem(a6)
move.l d0,a2
beq.s NoMemAddSec
jsr Forbid(a6)
move.l UnusedSectors(pc),NextInList(a2)
move.l a2,UnusedSectors
jsr Permit(a6)
addq.l #1,NumBlocks
moveq #1,d0
NoMemAddSec
move.l (a7)+,a2
rts
********************* Adds 256 sectors to the sector list
* AddDefaultSectors *
*********************
AddDefaultSectors
move.l #DefaultBuffers,d2
beq.s MemAddErr
AddNxSec
bsr.s AddSector
tst.l d0
beq.s MemAddErr
subq.l #1,d2
bne.s AddNxSec
MemAddErr
rts
************** Frees One sector used by the program
* FreeSector *
************** returns d0 = sector to free
FreeSector
move.l a3,-(sp)
move.l $4.w,a6
jsr Forbid(a6)
move.l UnusedSectors(pc),d0
beq.s DeAlcSector
move.l d0,a3
move.l NextInList(a3),UnusedSectors
bra.s FreeSec
DeAlcSector
move.l LastSector(pc),d0
beq.s NoSects
move.l d0,a3
bsr RemoveSector
move.w WhichDrive(a3),d0
lea NumBuffers(pc),a0
subq.l #1,0(a0,d0.w)
FreeSec
subq.l #1,NumBlocks
move.l a3,a1
move.l #SectorSize,d0
jsr FreeMem(a6)
move.l a3,d0
NoSects jsr Permit(a6)
move.l (sp)+,a3
rts
************** Copies $200 bytes from (a0)+ to (a1)+
* CopySector *
**************
CopySector
movem.l d0/d1/d2/d3/d4/d5/d6/d7/a2/a3/a4/a5/a6,-(a7)
REPT 9
movem.l (a0)+,d0/d1/d2/d3/d4/d5/d6/d7/a2/a3/a4/a5/a6
movem.l d0/d1/d2/d3/d4/d5/d6/d7/a2/a3/a4/a5/a6,(a1)
lea $34(a1),a1
ENDR
movem.l (a0)+,d0/d1/d2/d3/d4/d5/d6/d7/a2/a3/a4
movem.l d0/d1/d2/d3/d4/d5/d6/d7/a2/a3/a4,(a1)
movem.l (a7)+,d0/d1/d2/d3/d4/d5/d6/d7/a2/a3/a4/a5/a6
rts
**************** Removes Sector a3 from sector list.
* RemoveSector *
****************
RemoveSector
move.l NextHash(a3),d0 Remove sector from hash list
beq.s NoNxHash
move.l d0,a0
move.l PrevHash(a3),PrevHash(a0)
NoNxHash
move.l PrevHash(a3),a0
move.l d0,NextHash(a0)
move.l NextInList(a3),d0 Remove sector from sector list
beq.s NoNext
move.l d0,a0
move.l PrevInList(a3),PrevInList(a0)
DoPrev move.l PrevInList(a3),d0
beq.s NoPriorSec
move.l d0,a0
move.l NextInList(a3),NextInList(a0)
rts
NoNext move.l PrevInList(a3),LastSector Deleting last sector in list
bra.s DoPrev
NoPriorSec
move.l NextInList(a3),FirstSector Deleting first sector in list
rts
**************** Inserts sector a3 into cache list at 1st position
* Add1stSector * a2 = Hash chain to add to
****************
Add1stSector
move.l (a2),d0 Insert sector into hash chain
beq.s No2ndHash
move.l d0,a0
move.l a3,PrevHash(a0)
No2ndHash
move.l a3,(a2)
move.l a2,PrevHash(a3)
move.l d0,NextHash(a3)
move.l FirstSector(pc),d0 Insert sector into sector list
move.l a3,FirstSector
clr.l PrevInList(a3)
move.l d0,NextInList(a3)
bne.s Not1stSec
move.l a3,LastSector
rts
Not1stSec
move.l d0,a0
move.l a3,PrevInList(a0)
rts
***************** Read sector from cache
* ReadFromCache *
*****************
ReadFromCache
movem.l a3/a4/a6,-(a7)
move.l a0,a3
move.l a1,a4
move.l $4.w,a6
jsr Forbid(a6)
bsr RemoveSector
bsr.s Add1stSector
lea Sector(a3),a0
move.l IO_DATA(a4),a1
bsr CopySector
clr.b IO_ERROR(a4)
move.l #$200,IO_SIZE(a4)
addq.l #1,TotalRHits
lea NumReadHits(pc),a0
addq.l #1,0(a0,d2.w)
btst #1,IO_FLAGS(a4)
bne.s NoRdMsg
and.b #$fe,IO_FLAGS(a4) SendIO, so send done message
move.l a4,a1
jsr ReplyMsg(a6)
NoRdMsg move.l a4,a1
jsr Permit(a6)
movem.l (a7)+,a3/a4/a6
rts
**************** Copies data from sector to be written into a buffer
* WriteToCache *
****************
WriteToCache
movem.l a1/a3/a4/a6,-(a7)
move.l a1,a4
move.l $4.w,a6
jsr Forbid(a6)
move.l a4,a1
bsr FindSector
beq.s WriteToSector
move.l a0,a3
bsr RemoveSector
InsertWrite
bsr Add1stSector
move.l IO_DATA(a4),a0
lea Sector(a3),a1
bsr CopySector
NoWtStrucs
jsr Permit(a6)
movem.l (sp)+,a1/a3/a4/a6
rts
WriteToSector
bsr AllocateSector
tst.l d0
beq.s NoWtStrucs
bra.s InsertWrite
************** Disk changed, so flush all buffers used by drive d2
* DiskChange *
**************
DiskChange
movem.l a3/a4/a6,-(a7)
move.l $4.w,a6
jsr Forbid(a6)
lea NumBuffers(pc),a4
lea 0(a4,d2.w),a4
move.l FirstSector(pc),a3
FreeNextSec
move.l a3,d0
beq.s EndDelSectors
cmp.w WhichDrive(a3),d2
bne.s SkipSector
subq.l #1,(a4)
bsr RemoveSector
move.l NextInList(a3),d0
move.l UnusedSectors(pc),NextInList(a3)
move.l a3,UnusedSectors
move.l d0,a3
bra.s FreeNextSec
SkipSector
move.l NextInList(a3),a3
bra.s FreeNextSec
EndDelSectors
jsr Permit(a6)
movem.l (a7)+,a3/a4/a6
rts
****************** Grabs the next free sector, or deallocates the first
* AllocateSector * one. Then fills in some info. a4 = IOrequest
****************** returns d0=sector structure (0=error)
AllocateSector
move.l UnusedSectors(pc),d0
beq.s DeAllocSector
move.l d0,a3
move.l NextInList(a3),UnusedSectors
FillStrucInfo
move.l IO_OFFSET(a4),d0
move.l d0,SectorOffset(a3)
move.w d2,WhichDrive(a3)
lsr.l #7,d0
and.l #$1fc,d0
lea SectorHeaders(pc),a2
add.w d0,a2
lea NumBuffers(pc),a0
addq.l #1,0(a0,d2.w)
move.l a3,d0
NoSectors
rts
DeAllocSector
move.l LastSector(pc),d0
beq.s NoSectors
move.l d0,a3
bsr RemoveSector
move.w WhichDrive(a3),d0
lea NumBuffers(pc),a0
subq.l #1,0(a0,d0.w)
bra.s FillStrucInfo
****************** Saves sector being read in
* SaveReadSector *
******************
SaveReadSector
movem.l a3/a4/a6,-(sp)
move.l a1,a4
bsr.s AllocateSector
tst.l d0
beq.s NoRdStrucs
WaitRdSector
move.l a4,a1
move.l $4.w,a6
jsr CheckIO(a6)
tst.l d0
bne.s RdDone
move.l GfxBase,a6
jsr WaitTOF(a6)
bra.s WaitRdSector
RdDone
jsr Forbid(a6)
bsr Add1stSector
move.l IO_DATA(a4),a0
lea Sector(a3),a1
bsr CopySector
NoRdStrucs
move.l $4.w,a6
jsr Permit(a6)
movem.l (sp)+,a3/a4/a6
rts
SetColour0
moveq #0,d0
SetCol move.l RastPort(pc),a1
move.l GfxBase,a6
jmp SetAPen(a6)
SetColour1
moveq #1,d0
bra.s SetCol
SetColour2
moveq #2,d0
bra.s SetCol
SetColour3
moveq #3,d0
bra.s SetCol
************** divides d1/d0, result in d0, remainder in d1
* LongDivide *
************** uses shift & subtract method
LongDivide
movem.l d2/d3/d4,-(sp)
move.l d0,d4
eor.l d1,d4 d4 is sign of result
move.l d0,d2 make both parameters positive
beq.s DivideBy0
bpl.s div0p
neg.l d2
div0p tst.l d1
bpl.s div1p
neg.l d1
div1p
moveq #$1f,d3 transfer divsor to top bit positions
ToEnd add.l d2,d2
dbcs d3,ToEnd
roxr.l #1,d2
neg.w d3
add.w #$1f,d3 d3 = number of times to shift
moveq #0,d0
nextbit add.l d0,d0
cmp.l d2,d1
bcs.s nosub
addq.w #1,d0
sub.l d2,d1
nosub lsr.l #1,d2
dbra d3,nextbit
tst.l d4
bpl.s divpos
neg.l d0
divpos movem.l (sp)+,d2/d3/d4
rts
DivideBy0
moveq #-1,d0 prevent divide by 0 crashing
bra.s divpos
************ calculates d0 = d0 * d1 for long integers
* LongMult *
************
LongMult
movem.l d1/d2/d3,-(a7)
move.w d1,d2
mulu d0,d2
move.l d1,d3
swap d3
mulu d0,d3
swap d3
clr.w d3
add.l d3,d2
swap d0
mulu d1,d0
swap d0
clr.w d0
add.l d2,d0
movem.l (a7)+,d1/d2/d3
rts
IntBase dc.l 0
GfxBase dc.l 0
DosBase dc.l 0
TrackBase dc.l 0
StartSP dc.l 0
FontAttr dc.l FontName font structure for topaz 8
dc.w 8,0
TopazFont dc.l 0
FewerButton dc.l 0 Next gadget
dc.w $a,$57,$54,$d GadX,GadY, widths
FewerGadgFlags dc.w 0 Flags
dc.w 3
dc.w 1
dc.l 0,0,0,0,0
dc.w FewerGadget
dc.l 0
MoreButton dc.l FewerButton Next gadget
dc.w $15b,$57,$43,$d GadX,GadY, widths
MoreGadgFlags dc.w 0 Flags
dc.w 3 Activation
dc.w 1 Type
dc.l 0,0 Renders
dc.l 0,0,0 Intuitext,Mutual Exclude,Special Info
dc.w MoreGadget Gadget ID
dc.l 0
MyWindow
dc.w 220,0 leftedge,TopEdge
dc.w WindowSmallX,WindowSmallY Width,height
dc.b 0,1 Pens
dc.l CLOSEWINDOW+GADGETUP+GADGETDOWN+MENUPICK IDCMP flags
dc.l WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE+NOCAREREFRESH
dc.l MoreButton 1st Gadget
dc.l 0 checkmark
dc.l 0 title (filled in later)
dc.l 0,0 current screen,bitmap
dc.w 0,0,WindowBigX,WindowBigY Min sizes,Max sizes
dc.w 1 Workbenchscreen
Window dc.l 0
MorePressed dc.b 0
FewerPressed dc.b 0
Signals dc.l 0 Signals used by program to wait for
RastPort dc.l 0
ForcePrint dc.b 0
GadgetSmall dc.b -1
TrackdiskIOreq
TimerIOreq ds.b IOSTD_SIZE
TrackdiskPort
TimerPort ds.b MP_SIZE
TimerPortOk dc.l 0
ProgramPort ds.b MP_SIZE
Date ds.b ds_SIZEOF
DevUnits dc.l 0,0,0,0
SectorHeaders ds.l $80
FirstSector dc.l 0 1st & last sectors for allocation/deallocation
LastSector dc.l 0
UnusedSectors dc.l 0
TotalReads dc.l 0
LastTotalReads dc.l -1
TotalWrites dc.l 0
LastTotalWrites dc.l -1
TotalRHits dc.l 0
LastTotalRHits dc.l -1
NumBlocks dc.l 0 Number of allocated blocks
LastNumBlocks dc.l -1 last number of blocks
NumReads dc.l 0,0,0,0 Number of reads for drives
dc.l -1,-1,-1,-1 last number of reads
NumWrites dc.l 0,0,0,0
dc.l -1,-1,-1,-1
NumReadHits dc.l 0,0,0,0
dc.l -1,-1,-1,-1
NumBuffers dc.l 0,0,0,0
dc.l -1,-1,-1,-1